#pragma once
#include "log.hpp"
#include <iostream>
#include <unistd.h>
#include <sys/types.h>        
#include <arpa/inet.h>  
#include <sys/socket.h>

extern LOG lg;

class Sockets
{
public:
    Sockets()
    {
    }

    int Getsocketfd() const
    {
        return socket_;
    }

    bool Socket()
    {
        socket_ = socket(AF_INET, SOCK_STREAM, 0); // 创建TCP套接字
        if (socket_ < 0)
        {
            lg(FATAL, "socket create error, sockfd: %d", socket_);
            return false;
        }
        else
        {
            lg(INFO, "socket create success, sockfd: %d", socket_);
            return true;
        }

        int reuse = 1;
        if(setsockopt(socket_, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse))) return true;
        else return false;
       
    }

    bool Bind(uint16_t port)
    {
        struct sockaddr_in local;
        socklen_t len = sizeof(local);
        memset(&local, 0, sizeof(local));
        local.sin_family = AF_INET; // IPv4
        local.sin_port = htons(port); // 将端口号转换为网络字节序
        local.sin_addr.s_addr = INADDR_ANY; // 监听所有IP地址的请求

        if (bind(socket_, (struct sockaddr*)&local, len) < 0)
        {
            lg(FATAL, "bind error, sockfd: %d", socket_);
            return false;
        }
        else
        {
            lg(INFO, "bind success, sockfd: %d", socket_);
            return true;
        }
    }

    bool Listen()
    {
        if (listen(socket_, 10) < 0) // 设置监听队列长度为10
        {
            lg(FATAL, "listen error, sockfd: %d", socket_);
            return false;
        }
        else
        {
            lg(INFO, "listen success, sockfd: %d", socket_);
            return true;
        }
    }

    bool Accept(int &client_socket, std::string &client_ip, uint16_t &client_port)
    {
        struct sockaddr_in client_addr;
        socklen_t len = sizeof(client_addr);
        client_socket = accept(socket_, (struct sockaddr*)&client_addr, &len); // 接受客户端连接
        if (client_socket < 0)
        {
            lg(WARNING, "accept error, errno: %d, err string: %s", errno, strerror(errno));
            return false;
        }
        else
        {
            client_ip = inet_ntoa(client_addr.sin_addr); // 获取客户端IP地址
            client_port = ntohs(client_addr.sin_port); // 获取客户端端口号
            return true;
        }
    }

    bool Connet(const std::string& server_ip , const uint16_t server_port)
    {
        struct sockaddr_in server_addr;
        bzero(&server_addr, sizeof(server_addr));
        server_addr.sin_family = AF_INET; // IPv4
        server_addr.sin_port = htons(server_port); 
        inet_pton(AF_INET, server_ip.c_str(), &server_addr.sin_addr);

        if(connect(socket_, (struct sockaddr*)&server_addr, sizeof(server_addr)) < 0)
        {
            return false;
        }
        else
        {
            return true;
        }
    }

    void Close()
    {
        if (socket_ > 0)
        {
            close(socket_);
        }
    }

    int GetSocket() const
    {
        return socket_;
    }

    ~Sockets()
    {
        
    }
private:
    int socket_; 
};